package edu.ynu.se.xiecheng.achitectureclass.service;

import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import edu.ynu.se.xiecheng.achitectureclass.common.service.LogicService;
import edu.ynu.se.xiecheng.achitectureclass.dao.CameraImageDao;
import edu.ynu.se.xiecheng.achitectureclass.entity.CameraImage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.stereotype.Service;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;

import java.time.Instant;
import java.util.*;

@Service
public class CameraService extends LogicService<CameraImageDao, CameraImage, Long> {

    private final String YS_LOGIN_URL = "http://42.193.14.241:7000/ysapi/subAccount/getToken";
    private final String YS_CAPTURE_URL = "https://open.ys7.com/api/lapp/device/capture";
    private final String ACCOUNT_ID = "1ca7f0ab24ba41b291346347ec30140e";

    private String accessToken;
    private long expireTime;

    @Autowired
    private OssService ossService;

    /**
     * 构造函数，注入 CameraImageDao
     */
    @Autowired
    public CameraService(CameraImageDao cameraImageDao) {
        super(cameraImageDao); // 调用父类构造函数，传入 CameraImageDao
    }

    /**
     * 获取或刷新访问令牌
     */
    private String getAccessToken() {
        // 如果token未过期，直接返回
        if (accessToken != null && Instant.now().toEpochMilli() < expireTime) {
            return accessToken;
        }

        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

        Map<String, String> body = new HashMap<>();
        body.put("accountId", ACCOUNT_ID);

        HttpEntity<Map<String, String>> request = new HttpEntity<>(body, headers);

        try {
            ResponseEntity<String> response = restTemplate.postForEntity(YS_LOGIN_URL, request, String.class);
            ObjectMapper mapper = new ObjectMapper();
            JsonNode root = mapper.readTree(response.getBody());

            if ("200".equals(root.get("code").asText())) {
                JsonNode data = root.get("data");
                accessToken = data.get("accessToken").asText();
                expireTime = data.get("expireTime").asLong();
                return accessToken;
            } else {
                throw new RuntimeException("获取萤石云token失败: " + root.get("msg").asText());
            }
        } catch (Exception e) {
            throw new RuntimeException("获取萤石云token失败", e);
        }
    }

    /**
     * 获取视频流URL和Token
     */
    public Map<String, String> getVideoUrlAndToken(String deviceSerial) {
        Map<String, String> result = new HashMap<>();
        result.put("url", "ezopen://open.ys7.com/" + deviceSerial + "/1.hd.live");
        result.put("accessToken", getAccessToken());
        return result;
    }

    /**
     * 抓拍图片
     */
    public String capture(String deviceSerial) {
        RestTemplate restTemplate = new RestTemplate();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> body = new LinkedMultiValueMap<>();
        body.add("accessToken", getAccessToken());
        body.add("deviceSerial", deviceSerial);
        body.add("channelNo", "1");
        body.add("quality", "3"); // 1080P

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<>(body, headers);

        try {
            ResponseEntity<String> response = restTemplate.postForEntity(YS_CAPTURE_URL, request, String.class);
            ObjectMapper mapper = new ObjectMapper();
            JsonNode root = mapper.readTree(response.getBody());

            if ("200".equals(root.get("code").asText())) {
                return root.get("data").get("picUrl").asText();
            } else {
                throw new RuntimeException("抓拍失败: " + root.get("msg").asText());
            }
        } catch (Exception e) {
            throw new RuntimeException("抓拍失败", e);
        }
    }

    /**
     * 抓拍图片并保存到OSS
     */
    public Map<String, Object> captureAndSave(String deviceSerial) {
        // 1. 从萤石云获取图片URL
        String ysImageUrl = capture(deviceSerial);

        // 2. 上传到OSS并获取永久URL
        String ossUrl = ossService.uploadFromUrl(ysImageUrl, deviceSerial);

        // 3. 保存到数据库
        CameraImage cameraImage = new CameraImage();
        cameraImage.setDeviceSerial(deviceSerial);
        cameraImage.setImageUrl(ossUrl);
        cameraImage.setCaptureTime(new Date());
        cameraImage = POST(cameraImage); // 调用父类的 POST 方法保存实体

        // 4. 返回结果
        Map<String, Object> result = new HashMap<>();
        result.put("id", cameraImage.getId());
        result.put("url", ossUrl);
        result.put("captureTime", cameraImage.getCaptureTime());
        return result;
    }

    /**
     * 获取设备的历史图片
     */
    public List<Map<String, Object>> getHistoryImages(String deviceSerial) {
        List<CameraImage> images = getDAO().findByDeviceSerialOrderByCaptureTimeDesc(deviceSerial);
        List<Map<String, Object>> result = new ArrayList<>();

        for (CameraImage image : images) {
            Map<String, Object> imageInfo = new HashMap<>();
            imageInfo.put("id", image.getId());
            imageInfo.put("url", image.getImageUrl());
            imageInfo.put("captureTime", image.getCaptureTime());
            result.add(imageInfo);
        }

        return result;
    }

    /**
     * 获取指定ID的图片URL
     */
    public String getImageUrl(Long imageId) {
        CameraImage image = GET(imageId); // 调用父类的 GET 方法查询实体
        if (image == null) {
            throw new RuntimeException("图片不存在");
        }
        return image.getImageUrl();
    }
}